﻿using System.Threading;
using System.Windows.Forms;
using Common.Entities;

namespace Infrastructure.Gateways
{
    public abstract class BaseLoginGateway : ApplicationContext
    {
        private const string ValueAttribute = "value";
        private const string ClickEvent = "click";

        protected WebBrowser _ieBrowser;
        protected GatewayDetails _gatewayDetails;
        protected AutoResetEvent _autoresetEvent;
        protected string _accessToken;

        public string AccessToken { get { return _accessToken; } }

        public void BuildGateway(AutoResetEvent resultEvent, GatewayDetails gatewayDetails)
        {
            _gatewayDetails = gatewayDetails;
            _autoresetEvent = resultEvent;

            var thrd = new Thread(new ThreadStart(
                                      delegate
                                      {
                                          Initialize();
                                          Application.Run(this);
                                      }));

            // set thread to STA state before starting
            thrd.SetApartmentState(ApartmentState.STA);
            thrd.Start();
            WaitHandle.WaitAll(new[] { _autoresetEvent });
        }

        private void Initialize()
        {
            _ieBrowser = new WebBrowser();
            _ieBrowser.DocumentCompleted += IeBrowserDocumentCompleted;
            _ieBrowser.Navigate(_gatewayDetails.LoginUrl);
            //GetAccessTokenFromUrl("http://api.vkontakte.ru/blank.html#access_token=647531cd219208966e70cba7016e0be3a366e266e26d25e160128747c4ebecc&expires_in=86400&user_id=173261717");
        }

        void IeBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            var document = ((WebBrowser)sender).Document;
            if (document == null)
                return;

            if (document.Title != _gatewayDetails.LoginSuccessTitle)
            {

                SetValueForHtmlElement(_gatewayDetails.UserNameHtmlElementId, ValueAttribute, _gatewayDetails.UserName);
                SetValueForHtmlElement(_gatewayDetails.PasswordHtmlElementId, ValueAttribute,
                                       _gatewayDetails.Password);

                InvokeMember(_gatewayDetails.SubmitButtonName, ClickEvent);
            }
            else if (document.Title == _gatewayDetails.LoginSuccessTitle)
            {
                if (document.Url != null)
                    _accessToken = GetAccessTokenFromUrl(document.Url.AbsoluteUri);
                _autoresetEvent.Set();
            }
        }

        protected abstract string GetAccessTokenFromUrl(string absoluteUri);

        protected abstract void SetValueForHtmlElement(string element, string attributeName, string value);

        protected abstract void InvokeMember(string element, string member);
    }
}